/**
* @program: src
*
* @description:注册逻辑
*
* @author: Mr.chen
*
* @create: 2020-11-05 10:34
**/
package account

import (
	"ydd-im/service/api/define"
	"ydd-im/service/api/models"
	"ydd-im/service/api/pkg/etcd"
	"ydd-im/service/api/services/wsservice/client"
	"ydd-im/service/api/tools/response"
	"ydd-im/service/api/tools/util"

	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"strings"
	"time"
)

type accountInfo struct {
	Username     string `json:"username"`
	Passwd     	 string `json:"password"`
	CreateTime time.Time  `json:"createtime"`
}

/**
 * 注册账号
 * @access  public
 * @param   string     username  账号
 * @param   string     passwd  密码
 * @param   string     userkey  用户id
 * @param   string     appkey  appkey
 * @return  mix
 */
func RegisterIsClusterUser (username,passwd,userkey,appkey string) (err error){
	if util.IsCluster() { // 如果是集群的
		//err = client.RegisterIsCluster(username,passwd,userkey,appkey)
		resp,err :=   client.RegisterIsClusterUser(username,passwd,userkey,appkey)
		if err !=nil {
			return err
		}
		if resp.Code == response.SuccessCode {
			return nil
		}else{
			return errors.New(resp.Msg)
		}
	}else{
		err =  Register(username,passwd,userkey,appkey)
		return  err
	}
}

/**
 *登录
 * @access  public
 * @param   string     username  账号
 * @param   string     passwd  密码
 * @param   string     client  客户端
 * @param   string     appkey  appkey
 * @return  map[string]interface{} data 用户信息
 * @return  error err
 */
func LoginIsClusterUser(c *gin.Context, username,passwd,clienttype,appkey string) (data interface{},err error) {
	if util.IsCluster() { // 如果是集群的
		resp,err :=   client.LoginIsClusterUser(c,username,passwd,clienttype,appkey)
		if err !=nil {
			return nil,err
		}
		var userInfo models.User
		if resp.Code == response.SuccessCode {
			json.Unmarshal(resp.Data,&userInfo)
			return userInfo,nil
		}else{
			return nil,errors.New(resp.Msg)
		}
	}else{
		data,err =   Login(username,passwd,clienttype,appkey)
		return data,err
	}
}
/**
 * 检查token的有效信息
 * @access  public
 * @param   string     token  用户token
 * @return  map[string]interface{} data 用户信息
 * @return  error err
 */
func GetUserInfoByTokenIsCluster(token string) (data []byte,err error) {
	if util.IsCluster() { // 如果是集群的
		resp,err :=   client.GetUserInfoByTokenIsCluster(token)

		if err !=nil {
			return nil,err
		}
		if resp.Code == response.SuccessCode {
			return resp.Data,nil
		}else{
			return nil,errors.New(resp.Msg)
		}
	}else{
		userInfo,err := GetUserInfoByToken(token)
		if err != nil {
			return nil,errors.New(err.Error())
		}
		userInfos,ok := userInfo.(models.User)
		if !ok {
			return nil,errors.New("查询用户信息有误")
		}
		// 将用户存放为session或者局部变量
		data, err = json.Marshal(userInfos)
		if err != nil {
			return nil,errors.New("查询用户信息有误")
		}
		return data,err
	}
}

/**
 *登录
 * @access  public
 * @param   string     username  账号
 * @param   string     passwd  密码
 * @param   string     client  客户端
 * @param   string     appkey  appkey
 * @return  map[string]interface{} data 用户信息
 * @return  error err
*/
func LoginIsCluster(username,passwd,clienttype,appkey string) (data interface{},err error) {
	if util.IsCluster() { // 如果是集群的
		resp,err :=   client.LoginIsCluster(username,passwd,clienttype,appkey)
		if err !=nil {
			return nil,err
		}
		if resp.Suc {
			return resp.Data,nil
		}else{
			return nil,errors.New(resp.Msg)
		}
	}else{
		data,err =   Login(username,passwd,clienttype,appkey)
		return data,err
	}
}


func Register(username,passwd,userkey,appkey string) (err error) {
	//校验是否为空
	username,err = new(models.Signconfigure).GetSystemId(appkey,username)
	if err != nil {
		return errors.New(err.Error())
	}
	if len(username) == 0 {
		return errors.New("系统账号不能为空")
	}
	if len(userkey) == 0 {
		userkey = util.GenUUID()
	}
	//判断是否被注册
	resp, err := etcd.Get(define.ETCD_PREFIX_ACCOUNT_INFO + username)
	if err != nil {
		return err
	}
	if resp.Count > 0 {
		return errors.New("系统账号已被注册")
	}
	// 加密密码
	//Salt := fmt.Sprintf("%06d", rand.Int31n(10000))
	Salt := util.GetRandomString(6)
	Passwd := util.MakePasswd(passwd, Salt)
	userList := strings.Split(username,"_")
	raccountInfo := accountInfo{
		Username:userList[1],
		Passwd:passwd,
		CreateTime: util.GetCurrentDateTime(),
	}
	jsonBytes, _ := json.Marshal(raccountInfo)
	// 查询当前的签名的id
	signconfigure := new(models.Signconfigure)
	signconfigureInfo,err :=signconfigure.GetSignconfigureInfo(userList[0],"md5")
	if err != nil {
		return errors.New(err.Error())
	}
	sid := signconfigureInfo.Id
	// 查询数据库是否存在
	user := new(models.User)
	userInfo,err :=user.GetUserInfo(userList[1],sid)
	if err != nil {
		return errors.New(err.Error())
	}
	if userInfo.Id >0 { // 存在当前用户，将期put在etcd上
		reaccountInfo := accountInfo{
			Username:userInfo.Username,
			Passwd:userInfo.Passwd,
			CreateTime:userInfo.Createat,
		}
		rejsonBytes, _ := json.Marshal(reaccountInfo)
		err = etcd.Put(define.ETCD_PREFIX_ACCOUNT_INFO+username, string(rejsonBytes))
		if err != nil {
			panic(err)
			return err
		}
		return errors.New("系统账号已被注册")
	}
	// 注册用户插入数据库
	User := &models.User{Passwd:Passwd,Salt:Salt,Username:userList[1],Avatar:"",Sex:models.SexNukown,Createat:util.GetCurrentDateTime(),Sid:sid,UserKey:userkey}
	_,err = user.AddUser(User)
	if err != nil {
		return err
	}
	//注册
	err = etcd.Put(define.ETCD_PREFIX_ACCOUNT_INFO+username, string(jsonBytes))
	if err != nil {
		panic(err)
		return err
	}
	return nil
}
// 登录流程
func Login(username,passwd,client,appkey string) (data interface{},err error) {
	username,err = new(models.Signconfigure).GetSystemId(appkey,username)
	if err != nil {
		return nil,errors.New(err.Error())
	}
	//校验是否为空
	if len(username) == 0 || len(client) == 0 {
		return nil,errors.New("重要参数不能为空")
	}
	userList := strings.Split(username,"_")
	// 查询当前的签名的id
	signconfigure := new(models.Signconfigure)
	signconfigureInfo,err :=signconfigure.GetSignconfigureInfo(userList[0],"md5")
	if err != nil {
		return nil,errors.New(err.Error())
	}
	sid := signconfigureInfo.Id
	// 查询数据库是否存在
	user := new(models.User)
	userInfo,err :=user.GetUserInfo(userList[1],sid)
	if err != nil {
		return nil,errors.New("获取用户信息失败")
	}
	if userInfo.Id >0 { // 存在当前用户，将期put在etcd上
		Passwd := util.MakePasswd(passwd, userInfo.Salt)
		if userInfo.Passwd != Passwd { // 密码不正确
			return nil,errors.New("密码不正确")
		}
		// 更新账号信息
		reaccountInfo := accountInfo{
			Username:userInfo.Username,
			Passwd:userInfo.Passwd,
			CreateTime:userInfo.Createat,
		}
		rejsonBytes, _ := json.Marshal(reaccountInfo)
		err = etcd.Put(define.ETCD_PREFIX_ACCOUNT_INFO+username, string(rejsonBytes))
		if err != nil {
			panic(err)
			return nil,err
		}
	}else{// 当前账号不存在
		return nil,errors.New("当前账号不存在")
	}
	// 生成token,插入数据库

	Salt := util.GetRandomString(8)
	token :=util.MakePasswd(userInfo.Username, fmt.Sprintf("%s%s",Salt,time.Now().Unix()))
	User := &models.UserToken{Username:userInfo.Username,Token:token,ClientId:"",LoginTime:time.Now(),ClientType:client,Userid:userInfo.Id,ExpireTime:time.Now().Add(168*time.Hour),Sid:sid}
	Usertoken := new(models.UserToken)
	_,err = Usertoken.AddUserToken(User)
	if err != nil {
		return nil, err
	}
	userInfo.Createatime = util.GetTimeDate(userInfo.Createat)
	userInfo.Token = token
	//data = make(map[string]interface{})
	//data["token"] = token
	//data["userInfo"] = userInfo
	b, _ := json.Marshal(&userInfo)
	_ = json.Unmarshal(b, &data)
	return data,nil
}
func CheckisRegister(requestId string) (err error) {
	//校验是否为空
	if len(requestId) == 0 {
		return errors.New("系统ID不能为空")
	}
	//判断是否被注册
	resp, err := etcd.Get(define.ETCD_PREFIX_ACCOUNT_INFO + requestId)
	if err != nil {
		return err
	}
	if resp.Count > 0 {
		return nil
	}else{
		return errors.New("该系统ID未注册")
	}
}
// 根据token获取用户信息
func GetUserInfoByToken(token string) (data interface{},err error) {
	//校验是否为空
	if len(token) == 0 {
		return nil,errors.New("token不能为空")
	}
	// 查询数据库是否存在
	usertoken := new(models.UserToken)
	userInfo,err :=usertoken.GetUserInfoByToken(token)
	if err != nil {
		return nil,errors.New("获取用户信息失败")
	}
	if userInfo.Id >0 { // 存在当前用户，将期put在etcd上
		return userInfo,nil
	}else{// 当前账号不存在
		return nil,errors.New("当前账号不存在")
	}

}

// 绑定token与客户端clientid
func UpdateUserInfoByToken(token,clientid string) (err error) {
	//校验是否为空
	if len(token) == 0 || len(clientid) == 0 {
		return errors.New("token,clientid不能为空")
	}
	// 查询数据库是否存在
	usertoken := new(models.UserToken)
	err =usertoken.UpdateUserInfoByToken(token,clientid)
	if err != nil {
		return errors.New("绑定token与客户lientid失败")
	}
	return nil
}

// 绑定token与客户端clientid
func UpdateUserTokenState(clientid string,Id int,state string) (err error) {
	//校验是否为空
	if len(clientid) == 0 || Id <=0 ||  len(state) == 0 {
		return errors.New("clientid,Id,state参数不能为空")
	}
	// 查询数据库是否存在
	usertoken := new(models.UserToken)
	err =usertoken.UpdateUserTokenState(clientid,Id,state)
	if err != nil {
		return errors.New("更改状态失败")
	}
	return nil

}
// 获取token中间件保存的信息
func GetMiddleUserInfo(c *gin.Context) (userInfo models.User,err error) {
	user,ok := c.Get("session_userinfo")
	userInfo = models.User{}
	if !ok {
		return userInfo, errors.New("获取用户信息失败")
	}
	// interface类型的只能断言，不能直接转换
	userStr := user.(string)
	err = json.Unmarshal([]byte(userStr),&userInfo)
	if err != nil {
		return userInfo, errors.New("转换用户信息失败")
	}
	return userInfo,nil
}

// 绑定token与客户端clientid
func AddUserToken(username,token,clientid,clienttype string,userid int) (err error) {
	//校验是否为空
	if len(token) == 0 || len(clientid) == 0 {
		return errors.New("token,clientid不能为空")
	}
	// 查询数据库是否存在
	usertoken :=&models.UserToken{Username:username,ClientId:clientid,Userid:userid,Token:token,LoginTime:time.Now(),ClientType:clienttype}
	model_usertoken := new(models.UserToken)
	theID,err :=model_usertoken.AddUserToken(usertoken)
	fmt.Println("======",theID)
	if err != nil {
		return errors.New("绑定token与客户lientid失败")
	}
	return nil

}

// 绑定userid与客户端clientid到user_clients表
func AddClientToUser(userid int,clientId string) (err error) {
	//校验是否为空
	if userid <= 0 || len(clientId) == 0 {
		return errors.New("userid,clientid不能为空")
	}
	// 查询数据库是否存在
	userToClient :=&models.UserClients{ClientId:clientId,Userid:userid,Creattime:time.Now()}
	modeluserToClient := new(models.UserClients)
	_,err = modeluserToClient.AddUserClients(userToClient)
	if err != nil {
		return errors.New("保存clientId失败")
	}
	return nil
}

// 获取messageArrive列表
func GetAllUserJoinSignList(sid int,userid int ) (user []models.User,err error) {
	//校验是否为空
	if  sid < 0  || userid <= 0{
		return user,errors.New("sid,token参数不合法")
	}
	// 查询当前的签名的id
	//signconfigure := new(models.Signconfigure)
	//signconfigureInfo,err :=signconfigure.GetSignconfigureInfo(appkey,"md5")
	//if err != nil {
	//	return user, errors.New(err.Error())
	//}
	// 查询数据库是否存在
	modeluser := new(models.User)
	user,err = modeluser.GetAllUserJoinSignList(sid,userid)
	if err != nil {
		return user,err
	}
	return user,nil
}